<template>
  <view class="container">
    <!-- 聊天消息区域 -->
    <scroll-view
      class="message-container"
      scroll-y="true"
      :scroll-top="scrollTop"
    >
      <view
        v-for="(message, index) in messages"
        :key="index"
        class="message-item"
        :class="message.role"
      >
        <view class="message-content">
          {{ message.content }}
        </view>
      </view>
    </scroll-view>

    <!-- 输入区域 -->
    <view class="input-container">
      <input
        v-model="inputMessage"
        class="input-box"
        placeholder="请输入问题..."
        @confirm="sendMessage"
      />
      <button class="send-btn" @click="sendMessage">发送</button>
    </view>
  </view>
</template>

<script>
import { fetchEventSource } from '@microsoft/fetch-event-source';

export default {
  data() {
    return {
      inputMessage: "",
      messages: [],
      scrollTop: 0,
      isStreaming: false,
      apiKey: "ragflow-FlNGNhZjVlMGVjNDExZjA5MDRlZWExN2",
      apiUrl: "http://175.178.238.5:8011",
      requestTask: null,
    };
  },
  methods: {
    handleResponse(data) {
      try {
        // 处理流式输出
        if (data.type === "stream") {
          // 如果是第一条流消息，添加一个AI消息
          if (!this.isStreaming) {
            this.isStreaming = true;
            this.messages.push({
              role: "assistant",
              content: data.content,
              isLoading: false,
            });
          } else {
            // 更新最后一条消息的内容
            const lastMessage = this.messages[this.messages.length - 1];
            lastMessage.content += data.content;
          }

          // 滚动到底部
          this.scrollToBottom();
        }
        // 处理流结束消息
        else if (data.type === "end") {
          this.isStreaming = false;
        }
        // 处理普通消息
        else {
          this.messages.push({
            role: "assistant",
            content: data.content,
            isLoading: false,
          });
          this.scrollToBottom();
        }
      } catch (error) {
        console.error("解析响应数据失败:", error);
      }
    },

    sendMessage() {
      if (!this.inputMessage.trim()) return;

      // 添加用户消息
      this.messages.push({
        role: "user",
        content: this.inputMessage,
        isLoading: false,
      });
      // #ifdef H5
      let eventSource = new EventSource('https://api.example.com/stream');
      eventSource.onmessage = (e) => {
        console.log('Received data:', e.data);
      };
      eventSource.onerror = (e) => {
        console.error('Stream error:', e);
      };
      // #endif
        fetchEventSource(`${this.apiUrl}/api/v1/chats_openai/2187a61a0ec811f09bebea17b84a9d2b/chat/completions`, {
        method: 'POST',  // 指定 POST 方法
        headers: {
          "Content-Type": "application/json",
          Authorization: "Bearer ragflow-FlNGNhZjVlMGVjNDExZjA5MDRlZWExN2",
        },
        body: JSON.stringify({  // 传递请求 Body
          model: "model",
          messages: [{ role: "user", content: this.inputMessage }],
          stream: true,
        }),
        onopen: (response) => {
          if (response.ok) console.log('连接成功');
          else throw new Error('连接失败');
        },
        onmessage: (event) => {
          console.log('收到数据:', event.data);  // 处理流式数据
        },
        onerror: (err) => {
          console.error('流错误:', err);
        }
      });
      // #ifndef H5
      // 发送HTTP POST请求
      this.requestTask = uni.request({
        url: `${this.apiUrl}/api/v1/chats_openai/2187a61a0ec811f09bebea17b84a9d2b/chat/completions`,
        method: "POST",
        data: {
          model: "model",
          messages: [{ role: "user", content: this.inputMessage }],
          stream: true,
        },
        header: {
          "Content-Type": "application/json",
          Authorization: "Bearer ragflow-FlNGNhZjVlMGVjNDExZjA5MDRlZWExN2",
        },
        responseType: "text",
        enableChunked: true, // 启用分块传输
        success: (res) => {
          // 流式数据处理
          let buffer = '';
          res.onChunkReceived = (chunk) => {
            buffer += chunk.data;

            // 处理可能的多条消息
            const messages = buffer.split('\n\n');
            buffer = messages.pop() || ''; // 保留未完整处理的部分

            messages.forEach(msg => {
              if (msg.trim()) {
                try {
                  const data = JSON.parse(msg.replace('data: ', ''));
                  this.handleResponse(data);
                } catch (e) {
                  console.error('解析流数据失败:', e);
                }
              }
            });
          };

          res.onSuccess = () => {
            console.log("流式请求完成");
            // 处理最后可能剩余的数据
            if (buffer.trim()) {
              try {
                const data = JSON.parse(buffer.replace('data: ', ''));
                this.handleResponse(data);
              } catch (e) {
                console.error('解析最后数据失败:', e);
              }
            }
          };
        },
        fail: (error) => {
          console.error("请求失败:", error);
          uni.showToast({
            title: "请求失败，请稍后再试",
            icon: "none",
          });
        },
        complete: () => {
          this.inputMessage = "";
          this.scrollToBottom();
        },
      });
      // #endif
    },

    scrollToBottom() {
      this.$nextTick(() => {
        this.scrollTop = 99999;
      });
    },
  },
};
</script>

<style scoped>
.container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  padding: 20rpx;
  box-sizing: border-box;
}

.message-container {
  flex: 1;
  overflow-y: auto;
  margin-bottom: 20rpx;
}

.message-item {
  margin-bottom: 20rpx;
  padding: 15rpx;
  border-radius: 10rpx;
  max-width: 80%;
}

.message-item.user {
  align-self: flex-end;
  background-color: #1989fa;
  color: white;
}

.message-item.assistant {
  align-self: flex-start;
  background-color: #f2f2f2;
  color: #333;
}

.input-container {
  display: flex;
  align-items: center;
  padding: 10rpx 0;
}

.input-box {
  flex: 1;
  height: 80rpx;
  border: 1px solid #ddd;
  border-radius: 40rpx;
  padding: 0 30rpx;
  margin-right: 20rpx;
}

.send-btn {
  width: 120rpx;
  height: 80rpx;
  line-height: 80rpx;
  text-align: center;
  background-color: #1989fa;
  color: white;
  border-radius: 40rpx;
}
</style>
